#ifndef XG_HEADER_SYSTEM
#define XG_HEADER_SYSTEM
//////////////////////////////////////////////////////////
#include "list.h"
#include "utils.h"

#ifndef HOST_IP
#define HOST_IP						"0.0.0.0"
#endif

#ifndef LOCAL_IP
#define LOCAL_IP					"127.0.0.1"
#endif

#ifndef DAEMON_ENVNAME
#define DAEMON_ENVNAME				"{daemonenvname}"
#endif

#ifndef SOCKECT_FRAMESIZE
#define SOCKECT_FRAMESIZE			8 * 1024
#endif

#ifndef SOCKECT_RECVTIMEOUT
#define SOCKECT_RECVTIMEOUT			10
#endif

#ifndef SOCKECT_SENDTIMEOUT
#define SOCKECT_SENDTIMEOUT			20
#endif

#ifndef SOCKET_CONNECT_TIMEOUT
#define SOCKET_CONNECT_TIMEOUT		3000
#endif

#ifndef SOCKET_TIMEOUT_LIMITSIZE
#define SOCKET_TIMEOUT_LIMITSIZE	10
#endif

#ifndef SOCKET_TIMEOUT_REDOTIMES
#define SOCKET_TIMEOUT_REDOTIMES	100
#endif

#ifdef XG_LINUX

#include <dlfcn.h>
#include <sys/epoll.h>
#include <sys/syscall.h>

typedef void* DLLFILE_T;
void* ThreadFunction(void*);

#define GetCurrentThreadId() syscall(SYS_gettid)

#else

typedef HANDLE DLLFILE_T;
DWORD WINAPI ThreadFunction(void*);

#endif

#define INVALID_DLLFILE		NULL

#ifndef XG_DLLFILE_MAXCNT
#define XG_DLLFILE_MAXCNT	1024
#endif

#ifdef __cplusplus
extern "C" {
#endif
	typedef enum
	{
		eREAD = 1,
		eWRITE = 2,
		eCREATE = 4,
		eHIDDEN = 8,
		eVISIBLE = 16
	} E_OPEN_MODE;

	inline static void SocketSetup()
	{
#ifdef XG_LINUX
		signal(SIGPIPE, SIG_IGN);
#else
		WSADATA data; WSAStartup(MAKEWORD(2, 2), &data);
#endif
	}

	int GetCpuCount();

	void Flush(HANDLE handle);

	void Close(HANDLE handle);

	int CalcCpuUseage(int delay);

	long long Tell(HANDLE handle);

	int RemoveFile(const char* path);
	 
	int GetPathType(const char* path);
	
	int RemoveFolder(const char* path);

	int CreateFolder(const char* path);
	
	int CreateNewFile(const char* path);
	
	int Read(HANDLE handle, void* data, int size);

	HANDLE OpenDisk(int diskno, E_OPEN_MODE mode);

	HANDLE OpenPartition(int ch, E_OPEN_MODE mode);

	int CloneFile(const char* src, const char* dest);

	HANDLE Open(const char* filename, E_OPEN_MODE mode);
	
	int Write(HANDLE handle, const void* data, int size);

	BOOL GetMemoryInfo(long long* total, long long* avail);
	
	long long Seek(HANDLE handle, long long offset, int mode);

	BOOL SetPathAttributes(const char* path, E_OPEN_MODE mode);

	BOOL GetCpuTime(long long* usr, long long* idle, long long* kernel);
	
	BOOL ReadSector(HANDLE handle, void* data, long long offset, long long num);

	BOOL WriteSector(HANDLE handle, const void* data, long long offset, long long num);
	
	BOOL GetDiskSpace(const char* path, long long* total, long long* avail, long long* free);

	BOOL IsSocketTimeout();

	void SocketClose(SOCKET sock);

	BOOL IsSocketClosed(SOCKET sock);

	int GetLocalAddress(char* host[]);
	
	BOOL IsLocalHost(const char* host);

	int SocketWriteEmptyLine(SOCKET sock);

	BOOL SocketSetSendTimeout(SOCKET sock, int ms);

	BOOL SocketSetRecvTimeout(SOCKET sock, int ms);

	SOCKET SocketConnect(const char* ip, int port);

	BOOL GetSocketAddress(SOCKET sock, char* address);

	int SocketReadLine(SOCKET sock, char* msg, int len);

	SOCKET ServerSocketAccept(SOCKET svr, char* address);

	const char* GetHostAddress(const char* host, char* ip);

	int SocketWriteLine(SOCKET sock, const char* msg, int len);

	SOCKET CreateServerSocket(const char* ip, int port, int backlog);

	SOCKET SocketConnectTimeout(const char* ip, int port, int timeout);

	int SocketPeek(SOCKET sock, void* data, int size);

	int SocketRead(SOCKET sock, void* data, int size);

	int SocketWrite(SOCKET sock, const void* data, int size);

	int SocketReadEx(SOCKET sock, void* data, int size, BOOL completed);

	int SocketWriteEx(SOCKET sock, const void* data, int size, BOOL completed);

	typedef struct __stWorkItem
	{
		void* data;
		SOCKET sock;
		void(*func)(struct __stWorkItem*);
	} stWorkItem;

	typedef struct __stThreadPool
	{
		int sz;
		int cnt;
		void* threads;
		MutexHandle lock;
	} stThreadPool;

	BOOL IsInvalidThread(THREAD_T thread);

	stThreadPool* ThreadPoolCreate(int maxsz);

	BOOL StartThread(stWorkItem item, const void* attr);

	BOOL ThreadPoolDoWork(stThreadPool* pool, stWorkItem item);

	void DllFileClose(DLLFILE_T handle);

	DLLFILE_T DllFileOpen(const char* path);

	void* DllFileGetAddress(DLLFILE_T handle, const char* name);
#ifdef __cplusplus
}
#endif

//////////////////////////////////////////////////////////
#endif